/**
 * Vitest 测试环境设置文件
 * 在所有测试运行前执行，用于配置全局测试环境
 */

import { config } from '@vue/test-utils'
import { beforeEach, vi } from 'vitest'

// Mock Electron APIs
const mockElectron = {
  ipcRenderer: {
    send: vi.fn(),
    sendSync: vi.fn(),
    on: vi.fn(),
    removeAllListeners: vi.fn()
  }
}

// Mock global Electron objects
Object.defineProperty(window, 'electron', {
  value: mockElectron,
  writable: true
})

// Mock _pre_ global object for preload APIs
const mockPreload = {
  browser: {
    send: vi.fn()
  },
  contextMenu: {
    show: vi.fn().mockResolvedValue(undefined)
  },
  popup: {
    show: vi.fn()
  },
  monitor: {
    getProcesses: vi.fn()
  },
  siteInfo: {
    get: vi.fn()
  },
  browsingHistory: {
    add: vi.fn(),
    search: vi.fn()
  },
  windows: {
    minimize: vi.fn(),
    maximize: vi.fn(),
    close: vi.fn()
  },
  generateTabId: vi.fn(() => Math.floor(Math.random() * 1000))
}

Object.defineProperty(window, '_pre_', {
  value: mockPreload,
  writable: true
})

// Mock localStorage and sessionStorage
function createStorageMock() {
  return {
    getItem: vi.fn(),
    setItem: vi.fn(),
    removeItem: vi.fn(),
    clear: vi.fn(),
    key: vi.fn(),
    length: 0
  }
}

Object.defineProperty(window, 'localStorage', {
  value: createStorageMock(),
  writable: true
})

Object.defineProperty(window, 'sessionStorage', {
  value: createStorageMock(),
  writable: true
})

// Mock ResizeObserver
global.ResizeObserver = vi.fn().mockImplementation(() => ({
  observe: vi.fn(),
  unobserve: vi.fn(),
  disconnect: vi.fn()
}))

// Mock IntersectionObserver
global.IntersectionObserver = vi.fn().mockImplementation(() => ({
  observe: vi.fn(),
  unobserve: vi.fn(),
  disconnect: vi.fn()
}))

// Mock matchMedia
Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: vi.fn().mockImplementation(query => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: vi.fn(),
    removeListener: vi.fn(),
    addEventListener: vi.fn(),
    removeEventListener: vi.fn(),
    dispatchEvent: vi.fn()
  }))
})

// Mock requestAnimationFrame
global.requestAnimationFrame = vi.fn(cb => setTimeout(cb, 0))
global.cancelAnimationFrame = vi.fn()

// Mock console methods to reduce noise in tests
global.console = {
  ...console,
  log: vi.fn(),
  warn: vi.fn(),
  error: vi.fn(),
  info: vi.fn(),
  debug: vi.fn()
}

// Configure Vue Test Utils global stubs
config.global.stubs = {
  // Vuetify 组件 stubs
  VApp: true,
  VMain: true,
  VContainer: true,
  VRow: true,
  VCol: true,
  VCard: true,
  VCardTitle: true,
  VCardText: true,
  VCardActions: true,
  VBtn: true,
  VIcon: true,
  VTextField: true,
  VSelect: true,
  VCheckbox: true,
  VRadio: true,
  VSwitch: true,
  VSlider: true,
  VDialog: true,
  VMenu: true,
  VTooltip: true,
  VSnackbar: true,
  VAlert: true,
  VProgressBar: true,
  VProgressCircular: true,
  VDivider: true,
  VSpacer: true,
  VList: true,
  VListItem: true,
  VListItemTitle: true,
  VListItemSubtitle: true,
  VNavigationDrawer: true,
  VAppBar: true,
  VToolbar: true,
  VTabs: true,
  VTab: true,
  VTabsWindow: true,
  VTabsWindowItem: true,
  VDefaultsProvider: true,

  // Router 相关
  RouterLink: true,
  RouterView: true
}

// Reset all mocks before each test
beforeEach(() => {
  vi.clearAllMocks()

  // Reset DOM
  document.body.innerHTML = ''
  document.head.innerHTML = ''

  // Reset global state
  if (window._pre_) {
    for (const api of Object.values(window._pre_)) {
      if (typeof api === 'object' && api !== null) {
        for (const method of Object.values(api)) {
          if (vi.isMockFunction(method)) {
            method.mockClear()
          }
        }
      }
    }
  }
})
